package com.bbx.taxi.client;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.app.Application;
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.LocationClientOption.LocationMode;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.bbx.androidapi.util.DebugUtil;
import com.bbx.androidapi.util.SharedPreUtil;
import com.bbx.api.gclient.GMsg;
import com.bbx.api.sdk.Config;
import com.bbx.api.sdk.SDK;
import com.bbx.api.sdk.model.base.BaseRequest;
import com.bbx.taxi.client.Bean.Line;
import com.bbx.api.sdk.model.passanger.Token;
import com.bbx.api.sdk.model.passanger.Return.ActivityContent;
import com.bbx.api.util.LogUtils;
import com.bbx.api.util.SharedPreEncryptUtil;
import com.bbx.taxi.client.Adapter.City.CityAdapter;
import com.bbx.taxi.client.Bean.City;
import com.bbx.taxi.client.Bean.LogMsg;
import com.bbx.taxi.client.Bean.Value;
import com.bbx.taxi.client.Bean.Attribute.MainAttribute;
import com.bbx.taxi.client.Bean.Message.Publisher;
import com.bbx.taxi.client.DB.CityDB;
import com.bbx.taxi.client.Service.LoginService;
import com.bbx.taxi.client.Task.MyActivityTask;
import com.bbx.taxi.client.Util.AppStarted;
import com.bbx.taxi.client.Util.HistoricCityUtils;
import com.bbx.taxi.client.Util.NetworkDetector;
import com.bbx.taxi.client.Util.RequestUtils;
import com.bbx.taxi.client.Util.ToCity2;
import com.bbx.taxi.client.Util.VersionUtils;
import com.bbx.taxi.client.Bean.Line.CitiesBean.AppCitysBean.ChildCitysBeanX;
import com.bbx.taxi.client.Bean.Line.CitiesBean.AppCitysBean.ChildCitysBeanX.ToCitiesBean;
import com.bbx.taxi.client.Bean.Line.CitiesBean.AppCitysBean.ChildCitysBeanX.ToCitiesBean.ChildCitysBean;
import com.bbx.taxi.client.Bean.Line.CitiesBean.AppCitysBean;

public class MyApplication extends Application implements
		OnGetGeoCoderResultListener {
	private CityDB cityDB;
	public static final int CITY_LIST_SCUESS = 0;
	private static final String FORMAT = "^[a-z,A-Z].*$";
	private static MyApplication mApplication;
	public static boolean isCityListComplite;
	public MyLocationListenner mMyLocationListener;
	public LocationClientOption option;// 设置定位信息
	public LocationClient locationclient;// 用来定位
	public BDLocation mLocation;
	public ReverseGeoCodeResult mResult;
	public String loctionType = "";// 定位类型
	public String loctionCity = "";// 定位城市
	public String loctionSnCity = "";// 市内定位城市
	public double longitude = 0;// 经度
	public double latitude = 0;// 纬度
	//定位失败的经纬度
	public LatLng ll_fail= new LatLng(24.489894, 118.187474);
	public static ArrayList<EventHandler> mListeners = new ArrayList<EventHandler>();
	/** 电话 */
	public String user_phone = "";
	/** 名字 */
	public String user_name = "";
	/** 性别 */
	public String user_sex = "";
	/** 用户类型type”:0乘客,1司机,2管理员 */
	public String user_type = "";
	/** token */
	public String token = "";
	/** uid */
	public String uid = "";
	public LoginService loginservice;
	/** 第一次打开客户端 ,用于判断活动*/
	public boolean isFirstClient2 = false;
	/** 第一次打开客户端 */
	public boolean isFirstClient = false;
	/** 第一次启动该mainActivity */
	public boolean isFirstActivity = true;
	private GeoCoder mSearch = null; // 地理编码
	/**用于判断是否调用startup接口，每次登陆跟唤醒都要调用*/
	private boolean isStartup=true;
	 public List<Activity> activityList = new LinkedList<Activity>();
	   // 添加Activity到容器中
     public void addActivity(Activity activity) {
             activityList.add(activity);
     }
	public String getUid() {
		if (uid.equals("")) {
			Token Mytoken = SharedPreEncryptUtil.getStringEncryptValue(this,
					SharedPreEncryptUtil.TokenAndUid, "");
			if (Mytoken != null && !Mytoken.equals(""))
				uid = Mytoken.uid;
		}
		return uid;
	}

	public String getToken() {
		if (token.equals("")) {
			Token Mytoken = SharedPreEncryptUtil.getStringEncryptValue(this,
					SharedPreEncryptUtil.TokenAndUid, "");
			if (Mytoken != null && !Mytoken.equals(""))
				token = Mytoken.access_token;
		}
		return token;
	}
    public boolean isLogin(){
    	if(mApplication.getUid() != null && !mApplication.equals("")
				&& mApplication.getToken() != null
				&& !mApplication.getToken().equals("")){
    		return true;
    	}
    	return false;
    }
	public void setUid(String uid) {
		this.uid = uid;
	}

	public void setToken(String token) {
		this.token = token;
	}

	public static Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case CITY_LIST_SCUESS:
				isCityListComplite = true;
				if (mListeners.size() > 0)// 通知接口完成加载
					for (EventHandler handler : mListeners) {
						handler.onCityComplite();
					}
				break;
			default:
				break;
			}
		}
	};

	public static synchronized MyApplication getInstance() {
		return mApplication;
	}

	@Override
	public void onCreate() {
		loctionCity = this.getString(R.string.default_city);
		// TODO Auto-generated method stub
		// 实例化ClientBox
		DebugUtil.isDebug = false;
		SDK.GetSDK().init(getApplicationContext());
		LogUtils.initConfig(this, Value.BBX_PATH);
		init();
		onLocation();
		// 加载城市
		initData();

	}
    
	public void init() {
		switch(VersionUtils.getVersionType(getApplicationContext())){
		case bbx:
			Config.APP=VersionUtils.isBBX;
			break;
		case tianshang:
			Config.APP=VersionUtils.isTSX;
			break;
		}
		// 获取本地存储的电话
		user_phone = SharedPreUtil.getStringValue(this,
				SharedPreEncryptUtil.phone, "");
		// 获取名字
		user_name = SharedPreUtil.getStringValue(this,
				SharedPreEncryptUtil.user_name, "");
		MainAttribute main = MainAttribute.getInstance();
		main.setTel(user_phone);
		main.setName((user_name != null && !user_name.equals("")) ? user_name
				: main.getName());
		setIsStartUp(true);
	}
	public String getLoctionCity(boolean isSn){
		if(isSn){
			return loctionSnCity!=null?loctionSnCity:"";
		}else{
			return loctionCity!=null?loctionCity:"";
		}
	}
	/**
	 * 定位城市
	 */
	public void onLocation() {
		SDKInitializer.initialize(this);
		loctionType = getApplicationContext()
				.getString(R.string.loctionType_no);
		option = new LocationClientOption();// 设置定位的一些信息
		option.setLocationMode(LocationMode.Hight_Accuracy);// 设置定位模式
		option.setOpenGps(true);// 是否打开gps
		option.setIsNeedAddress(true);
		option.setCoorType("bd09ll"); // 设置坐标类型为bd09ll
		option.disableCache(false); // 禁止启用缓存定位
		option.setScanSpan(1000); // 定时定位，每隔5秒钟定位一
		option.setNeedDeviceDirect(true);
		locationclient = new LocationClient(this.getApplicationContext());// 用来定位
	}
	/**
	 * 重新定位
	 */
	public void onStartLocation() {
		try{
		if(mMyLocationListener==null){
			LogUtils.e(LogMsg.LOCATION, "开始定位");
			locationclient.setLocOption(option);
			mMyLocationListener = new MyLocationListenner();
			locationclient.registerLocationListener(mMyLocationListener);
			locationclient.start();
		}
		}catch(Exception e){}
	};

	public void onStopLocation() {
		try{
		LogUtils.e(LogMsg.LOCATION, "取消定位");
		locationclient.setLocOption(null);
		locationclient.unRegisterLocationListener(mMyLocationListener);
		locationclient.stop();
		mMyLocationListener=null;
		}catch(Exception e){}
	}
	/**
	 * 修改定位
	 */
	public void onChangeLocation(int time){
		onStopLocation();
		option.setScanSpan(time);
		onStartLocation();
	}

	private void initData() {
		// TODO Auto-generated method stub
		mApplication = this;
	}
	public boolean isCityListComplite() {
		return isCityListComplite;
	}
	public List<AppCitysBean> list_startcity;
	public void setStarCity(List<AppCitysBean> list_startcity,boolean isSn){
		if(isSn){
		}else{
			this.list_startcity=list_startcity;
		}
	}
	public List<AppCitysBean> getStarCity(boolean isSn){
		if(isSn){
            return null;
		}else{
			return list_startcity;
		}
	}
	public List<ToCitiesBean> list_endcity;
	public List<ToCitiesBean> list_endcity_sn;
	public void setEndCity(List<ToCitiesBean> list_endcity,boolean isSn){
		if(isSn){
			this.list_endcity_sn=list_endcity;
		}else{
			this.list_endcity=list_endcity;
		}
	}
	public List<ToCitiesBean> getEndCity(boolean isSn){
		if(isSn){
			return list_endcity_sn;
		}else{
			return list_endcity;
		}
	}
	public void onPrepareStartCity(List<AppCitysBean> list_startcity,boolean isSn){
		isCityListComplite = false;
		setStarCity(list_startcity, isSn);
		mHandler.sendEmptyMessage(CITY_LIST_SCUESS);
	}
	public void onPrepareEndCity(List<ToCitiesBean> list_endcity,boolean isSn){
		isCityListComplite = false;
		setEndCity(list_endcity,isSn);
		mHandler.sendEmptyMessage(CITY_LIST_SCUESS);
	}


	public static abstract interface EventHandler {
		public abstract void onCityComplite();

		public abstract void onNetChange();
	}

	public void setEventHandler(EventHandler hEventHandler) {
		if (!mListeners.contains(hEventHandler))
			mListeners.add(hEventHandler);
	}

	public void removeEventHandler(EventHandler hEventHandler) {
		mListeners.remove(hEventHandler);
	}

	/**
	 * 定位SDK监听函数
	 */
	public class MyLocationListenner implements BDLocationListener {

		@Override
		public void onReceiveLocation(final BDLocation location) {
			// map view 销毁后不在处理新接收的位置
			if (location == null)
				return;
			mLocation = location;
			if (location.getLocType() == BDLocation.TypeGpsLocation) {
				// GPS定位
				loctionType = getApplicationContext().getString(
						R.string.loctionType_gps);
			} else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {
				// 网络定位
				loctionType = getApplicationContext().getString(
						R.string.loctionType_network);
			}
			LatLng ll= new LatLng(location.getLatitude(),location.getLongitude());
			if(ll.latitude!=0&&ll.longitude!=0){
				longitude = ll.longitude;
				latitude =ll.latitude;
			}
			
			if (location.getCity() != null&&!location.getCity().equals("null")) {
				Config.CITY=location.getCity();
				if(Value.appCity==null){
					Value.appCity=Config.CITY;
				}
				if(getIsStartUp()){
					RequestUtils.requesStartUp(getApplicationContext(),location.getProvince());
					setIsStartUp(false);
				}
				new AsyncTask<Void, Void, Void>() {
					@Override
					protected Void doInBackground(Void... params) {
						//判断城际
						if(ToCity2.isDistrictExist(location.getDistrict(),false)){
							loctionCity=location.getDistrict();
						}else{
							loctionCity = location.getCity();
						}
						//判断市内
						if(ToCity2.isDistrictExist(location.getDistrict(),true)){
							loctionSnCity=location.getDistrict();
						}else{
							loctionSnCity = location.getCity();
						}
						return null;
					}

					@Override
					protected void onPostExecute(Void result) {
						if (!mOnLocationResultListener_list.isEmpty()) {
							for (int i = 0; i < mOnLocationResultListener_list.size(); i++) {
								mOnLocationResultListener_list.get(i).onLocationResult(
										location);
							}
						}
						super.onPostExecute(result);
					}
				  	
				}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
				
			} else {
				onGeoCoder(latitude, longitude);
			}

		}

		public void onReceivePoi(BDLocation poiLocation) {
		}
	}

	/**
	 * 地理编码搜索
	 */
	public void onGeoCoder(double latitude, double longitude) {
		if (NetworkDetector.detect(this)) {
			LatLng ptCenter = new LatLng(latitude, longitude);
			if (ptCenter.latitude == 0 || ptCenter.longitude == 0) {
				if (!mOnLocationResultListener_list.isEmpty()) {
					for (int i = 0; i < mOnLocationResultListener_list.size(); i++) {
						mOnLocationResultListener_list.get(i).onLocationFail(true);
					}
				}
				return;
			}
			// 初始化搜索模块，注册事件监听
			mSearch = GeoCoder.newInstance();
			mSearch.setOnGetGeoCodeResultListener(this);
			// 反Geo搜索
			mSearch.reverseGeoCode(new ReverseGeoCodeOption()
					.location(ptCenter));
		} else {
			if (!mOnLocationResultListener_list.isEmpty()) {
				for (int i = 0; i < mOnLocationResultListener_list.size(); i++) {
					mOnLocationResultListener_list.get(i).onLocationFail(false);
				}
			}
		}
	}

	public ArrayList<OnLocationResultListener> mOnLocationResultListener_list = new ArrayList<OnLocationResultListener>();

	/**
	 * 自定义定位监听结果
	 */
	public interface OnLocationResultListener {
		/**
		 * 定位结果
		 */
		public void onLocationResult(BDLocation location);

		public void onLocationResult(ReverseGeoCodeResult result);

		public void onLocationFail(boolean isnet);
	}

	public void setOnLocationResultListener(
			OnLocationResultListener mOnLocationResultListener) {
		if (!mOnLocationResultListener_list.contains(mOnLocationResultListener))
			mOnLocationResultListener_list.add(mOnLocationResultListener);
	}

	public void removeOnLocationResultListener(
			OnLocationResultListener mOnLocationResultListener) {
		mOnLocationResultListener_list.remove(mOnLocationResultListener);
	}

	public ServiceConnection mSc = new ServiceConnection() {
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			loginservice = ((LoginService.MyBinder) service).getService();
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			loginservice = null;
		}
	};

	/**
	 * 地理编码结果（地理到经纬度的结果）
	 */
	@Override
	public void onGetGeoCodeResult(GeoCodeResult result) {
		// TODO Auto-generated method stub

	}

	/**
	 * 地理编码结果（经纬度到地址的结果）
	 */
	@Override
	public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
		if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR
				|| result.getPoiList() == null) {

		} else {
			mResult=result;
			loctionCity = result.getAddressDetail().city;
			if(loctionCity!=null){
			   Config.CITY=loctionCity;
				if(Value.appCity==null){
					Value.appCity=Config.CITY;
				}
			   if(getIsStartUp()){
					RequestUtils.requesStartUp(getApplicationContext(),result.getAddressDetail().province);
					setIsStartUp(false);
				}
			if (!mOnLocationResultListener_list.isEmpty()) {
				for (int i = 0; i < mOnLocationResultListener_list.size(); i++) {
					mOnLocationResultListener_list.get(i).onLocationResult(
							result);
				}
		      }
			}
		}

	}
	  public void exit() {
          for (Activity activity : activityList) {
                  activity.finish();
          }
  }
  public void setIsStartUp(boolean isStartup){
	  this.isStartup=isStartup;
  }
  public boolean getIsStartUp(){
	  return isStartup&&isLogin();
  }
}
